#include <memory>
#include <sstream>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <Presentation/IoManager.hpp>

#include <Mocks/Model/FibonacciNumberCalculatorMock.hpp>


using namespace testing;


namespace Fibonacci
{
namespace Presentation
{
namespace Testing
{


class IoManagerTester : public Test
{
public:
  IoManagerTester()
  {
    calculatorMock.reset(new StrictMock<Model::Testing::FibonacciNumberCalculatorMock>());
    manager.reset(new IoManager(ss, oss, calculatorMock));
  }

protected:
  // tested class:
  std::unique_ptr<IoManager> manager;

  // mocks:
  std::shared_ptr<Model::Testing::FibonacciNumberCalculatorMock> calculatorMock;

  std::stringstream ss;
  std::ostringstream oss;
};


TEST_F(IoManagerTester, InitializesInputStreamToThreeAndRunsIoManager)
{
  // given
  unsigned n = 3;
  ss << n;

  // when
  EXPECT_CALL(*calculatorMock, get(n)).WillOnce(Return(2u));
  manager->run();

  // then
  EXPECT_EQ("2\n", oss.str());
}
  
  
TEST_F(IoManagerTester, InitializesInputStreamToSixAndRunsIoManager)
{
  // given
  unsigned n = 6;
  ss << n;

  // when
  EXPECT_CALL(*calculatorMock, get(n)).WillOnce(Return(8u));
  manager->run();

  // then
  EXPECT_EQ("8\n", oss.str());
}


} // namespace Testing
} // namespace Presentation
} // namespace Fibonacci
